import json
import ast
from datetime import datetime
from tempfile import NamedTemporaryFile

from django.db import transaction
from rest_framework.views import APIView, Response, status
from rest_framework import viewsets, mixins
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from django.utils.encoding import escape_uri_path
from django.http import FileResponse

from apps.common.account.models import Account
from apps.pollution.utils import upload_file_to_oss
from .models import CompanySelfAssessment, FileTemplate, Answer
from .serializers import CompanySelfAssessmentSerializer, FileTemplateSerializer, AnswerSerializer, CompanySelfAssCheck
from .filters import AnswerFilter, CompanySelfAssFilter
from .utils import download_answer, download_self_ass, download_analysis
from utils.common import Pagination


class CompanySelfAssessmentViewSet(mixins.CreateModelMixin,
                                   mixins.ListModelMixin,
                                   mixins.RetrieveModelMixin,
                                   mixins.UpdateModelMixin,
                                   viewsets.GenericViewSet):
    queryset = CompanySelfAssessment.objects.all().select_related('check_people')
    serializer_class = CompanySelfAssessmentSerializer
    pagination_class = Pagination
    filter_class = CompanySelfAssFilter
    permission_classes = [IsAuthenticated, ]
    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
    ordering_fields = ['id', 'updated_time']

    def get_serializer_class(self):
        # if self.action == 'list':
        #     return AnswerListSerializer
        return self.serializer_class

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        if not request.user.is_superuser and instance.company_name != request.user.username:
            return Response({'message': '您没有权限获取该企业的信息'}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        if not request.user.is_superuser and instance.company_name != request.user.username:
            return Response({'message': '您没有权限获取该企业的信息'}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        return Response(serializer.data)

    @action(methods=['post'], detail=True, url_path='check')
    def do_check(self, request, pk=None):
        if not request.user.is_superuser:
            return Response({'message': '您没有权限进行检查'}, status=status.HTTP_403_FORBIDDEN)
        instance = self.get_object()
        context = self.get_serializer_context()
        serializer = CompanySelfAssCheck(instance, data=request.data, partial=True, context=context)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response(serializer.data)

    def list(self, request, *args, **kwargs):
        need_company_qs = Account.objects.filter(is_company=True, is_analysis=True).values_list("username", flat=True)
        if request.user.is_superuser:
            queryset = self.queryset
        else:
            queryset = self.queryset.filter(company_name=request.user.username)
        queryset = self.filter_queryset(queryset)
        queryset = queryset.filter(company_name__in=need_company_qs)

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        download = request.query_params.get('download', False)
        if download:
            data = queryset.values()
            check_people_ids = [i['check_people_id'] for i in data]
            check_people_qs = Account.objects.filter(id__in=check_people_ids).values()
            check_people_data = {i['id']: i for i in check_people_qs}
            for i in data:
                check_people_id = i['check_people_id']
                i['check_people_realname'] = check_people_data[check_people_id]['realname'] \
                    if check_people_id in check_people_data else ''
            file_name = '企业自评.xlsx'
            result = download_self_ass(data)
            with NamedTemporaryFile() as tmp:
                result.save(tmp.name)
                file = open(tmp.name, 'rb')
                response = FileResponse(file)
                response['Content-Type'] = "application/octet-stream"
                response['Content-Disposition'] = f"attachment; filename={escape_uri_path(file_name)}"
                response['Access-Control-Expose-Headers'] = 'Content-Disposition'
                return response

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['post'], detail=False, url_path='upload_file')
    def upload_file_to_oss(self, request, pk=None):
        # 上传文件到阿里云oss
        file = request.data.get('file', None)
        dir_path = request.data.get('dir', None)
        if not file:
            return Response({'message': '需要文件'}, status=status.HTTP_400_BAD_REQUEST)
        if not dir_path:
            return Response({'message': '错误，需要路径'}, status=status.HTTP_400_BAD_REQUEST)
        company_name = request.user.username
        now_str = datetime.now().strftime('%Y%m%d%H%M')
        file_name = f"{company_name}-{now_str}-{file.name}"
        file_path = upload_file_to_oss(file, file_name, file_path=dir_path)
        if not file_path:
            return Response({'message': '上传失败'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'data': file_path})


class FileTemViewSets(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = FileTemplate.objects.all()
    serializer_class = FileTemplateSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated, ]
    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)


class AnswerViewSet(mixins.ListModelMixin,
                    viewsets.GenericViewSet):
    queryset = Answer.objects.all()
    serializer_class = AnswerSerializer
    filter_class = AnswerFilter
    pagination_class = Pagination
    # permission_classes = [IsAuthenticated, ]
    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)

    def list(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return Response({'message': '无权限访问'}, status=status.HTTP_403_FORBIDDEN)
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        download = request.query_params.get('download', False)
        if download:
            data = queryset.values()
            file_name = '查询结果.xlsx'
            result = download_answer(data)
            with NamedTemporaryFile() as tmp:
                result.save(tmp.name)
                file = open(tmp.name, 'rb')
                response = FileResponse(file)
                response['Content-Type'] = "application/octet-stream"
                response['Content-Disposition'] = f"attachment; filename={escape_uri_path(file_name)}"
                response['Access-Control-Expose-Headers'] = 'Content-Disposition'
                return response

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='download_analysis')
    def download_analysis(self, request, pk=None):
        data = Answer.objects.filter(batch_num=2).values('answer', 'company_name')
        file_name = '分析结果.xlsx'
        result = download_analysis(data)
        with NamedTemporaryFile() as tmp:
            result.save(tmp.name)
            file = open(tmp.name, 'rb')
            response = FileResponse(file)
            response['Content-Type'] = "application/octet-stream"
            response['Content-Disposition'] = f"attachment; filename={escape_uri_path(file_name)}"
            response['Access-Control-Expose-Headers'] = 'Content-Disposition'
            return response


class UploadImageView(APIView):

    def post(self, request):
        # 上传文件到阿里云oss
        file = request.data.get('file', None)
        dir_path = request.data.get('dir', None)
        if not file:
            return Response({'message': '需要文件'}, status=status.HTTP_400_BAD_REQUEST)
        if not dir_path:
            return Response({'message': '错误，需要路径'}, status=status.HTTP_400_BAD_REQUEST)
        now_str = datetime.now().strftime('%Y%m%d%H%M')
        file_name = f"{now_str}-{file.name}"
        file_path = upload_file_to_oss(file, file_name, file_path=dir_path)
        if not file_path:
            return Response({'message': '上传失败'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'data': file_path})